package com.meego.common.crypto;

import com.meego.common.config.Config;
import com.meego.common.log.GA;
import com.meego.common.util.ByteUtils;
import com.meego.common.util.StringUtils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class KeyStore {

    private boolean mMassiveSecurityHole;
    private MeegoKeyStore mKeyStore;
    private static KeyStore instance;
    private static char[] hex = "0123456789abcdef".toCharArray();
    public static byte[] editorSeed = {56, -68, -95, -74, 38, 126, -30, 98, -121, -115, 7, 1, 106, -79, -34, -52};

    public static KeyStore getInstance() {
        if (instance == null) {
            instance = new KeyStore();
        }
        return instance;
    }

    public KeyStore() {
        this(Config.getStrConfig("vs.dlm.zmkfile", "vs.zmk"), Config.getIntConfig("dlm.debug_stk_implementation", 0) == 1);
    }

    public String getStoreKey(int index) {
        String key = null;
        if (index == 0) {
            key = ByteUtils.bytesToString(editorSeed);
        }
        return key;
    }

    public KeyStore(String file, boolean security) {
        this.mMassiveSecurityHole = security;

        this.mKeyStore = new MeegoKeyStore();
        try {
            FileInputStream fis = new FileInputStream(file);
            this.mKeyStore.load(fis, ByteUtils.bytesToString(editorSeed).toCharArray());
        } catch (IOException ex) {
            GA.crypto.error("Exception in loading of KeyStore", ex);

            GA.crypto.error("Loading of KeyStore failed.");
        }
    }

    public String get(String aKey) {
        String value = this.mKeyStore.getString(aKey);
        if (isMassiveSecurityHole()) {
            GA.crypto.debug("KeyStore param " + aKey + ":" + value);
        }
        return value;
    }

    public void setKey(String aKey, byte[] value, String keystore) throws FileNotFoundException, IOException {
        this.mKeyStore.add(aKey, value);
        if (keystore == null) {
            this.mKeyStore.save(new FileOutputStream("../etc/ops.source"), ByteUtils.bytesToString(editorSeed).toCharArray());
        } else {
            this.mKeyStore.save(new FileOutputStream(keystore), ByteUtils.bytesToString(editorSeed).toCharArray());
        }
    }

    public byte[] getKey(String aKey) {
        return this.mKeyStore.get(aKey);
    }

    public byte[] getKey(String aKey, int size) {
        byte[] key = this.mKeyStore.get(aKey);
        if (key == null) {
            GA.crypto.warn("KeyStore key " + aKey + " not found");
            return null;
        }

        if (key.length != size / 8) {
            GA.crypto.warn("KeyStore key " + aKey + " invalid length. Expected:" + size + " was: " + key.length * 8);
            return null;
        }

        logKey("KeyStore Key " + aKey + ":", key);

        return key;
    }

    public boolean isMassiveSecurityHole() {
        return this.mMassiveSecurityHole;
    }

    public byte[] fromHex(String aString) {
        if ((aString.length() & 0x1) == 1) {
            return null;
        }

        byte[] result = new byte[aString.length() >> 1];
        for (int scan = 0; scan < result.length; scan++) {
            int hi = fromHex(aString.charAt(scan << 1));
            if (hi == -1) {
                return null;
            }
            int lo = fromHex(aString.charAt((scan << 1) + 1));
            if (lo == -1) {
                return null;
            }
            result[scan] = (byte) ((hi << 4 & 0xF0) + (lo & 0xF));
        }

        return result;
    }

    private int fromHex(char c) {
        if ((c >= '0') && (c <= '9')) {
            return c - '0';
        }
        if ((c >= 'a') && (c <= 'f')) {
            return c - 'a' + 10;
        }
        if ((c >= 'A') && (c <= 'F')) {
            return c - 'A' + 10;
        }
        return -1;
    }

    public void logKey(String prefix, byte[] key) {
        if (!isMassiveSecurityHole()) {
            return;
        }
        char[] log = new char[key.length << 1];
        for (int scan = 0; scan < key.length; scan++) {
            log[(scan << 1)] = hex[(key[scan] >> 4 & 0xF)];
            log[((scan << 1) + 1)] = hex[(key[scan] & 0xF)];
        }
        GA.crypto.debug(prefix + new String(log));
    }

    public void logCipherText(String prefix, String text) {
        GA.crypto.info(logText(prefix, text));
    }

    public void logPlainText(String prefix, String text) {
        if (!isMassiveSecurityHole()) {
            return;
        }
        GA.crypto.debug(logText(prefix, text));
    }

    private String logText(String prefix, String text) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(prefix);
        buffer.append(" [");
        buffer.append(StringUtils.killUnicode(text));
        buffer.append(']');
        return buffer.toString();
    }

    public static enum KeyStoreType {

        STK;
    }
}
